package sis.security;/*
 * @auther 顶风少年
 * @mail dfsn19970313@foxmail.com
 * @date 2019-07-31 14:06
 * @notify
 * @version 1.0
 */

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;

// 动态代理需要的第三个参数
public class SecureProxy implements InvocationHandler {

    //方法列表
    private List<String> secureMethods;
    //需要增强的对象 我称之为代理对象的前身
    private Object target;

    //构造子,接收代理对象前身,和该前身都有哪些方法需要动态代理
    public SecureProxy(Object target, String... secureMethods) {
        this.target = target;
        this.secureMethods = Arrays.asList(secureMethods);
    }

    //最终每个执行方法都会 经过这个方法
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        try {
            //如果这个方法不应该被代理则抛出异常.
            if (isSecure(method)) {
                throw new PermissionException();
            }
            //执行 对象前身的方法.
            return method.invoke(target,args);
        } catch (InvocationTargetException e) {
            throw e.getTargetException();
        }
    }

    //查询当前代理对象执行的方法,是否在 安全方法列表(所谓安全方法,就是这个方法到底需不需要被代理改变)
    private boolean isSecure(Method method) {
        return secureMethods.contains(method.getName());
    }
}
